package com.ruoyi.common.utils.processor;

import com.ruoyi.common.annotation.FloatPrecision;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.RoundingMode;

public class FloatPrecisionProcessor {

    /**
     * 处理对象中所有带有@FloatPrecision注解的浮点数字段
     */
    public static Object process(Object obj) {
        Class<?> clazz = obj.getClass();
        for (Field field : clazz.getDeclaredFields()) {
            if (field.isAnnotationPresent(FloatPrecision.class)) {
                processField(obj, field);
            }
        }
        return obj;
    }

    private static void processField(Object obj, Field field) {
        try {
            field.setAccessible(true);
            FloatPrecision annotation = field.getAnnotation(FloatPrecision.class);

            if (field.getType() == float.class || field.getType() == Float.class) {
                float originalValue = field.getFloat(obj);
                float processedValue = roundFloat(originalValue, annotation.value(), annotation.roundingMode());
                field.setFloat(obj, processedValue);
            } else if (field.getType() == double.class || field.getType() == Double.class) {
                double originalValue = field.getDouble(obj);
                double processedValue = roundDouble(originalValue, annotation.value(), annotation.roundingMode());
                field.setDouble(obj, processedValue);
            }
        } catch (IllegalAccessException e) {
            throw new RuntimeException("Failed to process float precision for field: " + field.getName(), e);
        }
    }

    private static float roundFloat(float value, int scale, RoundingMode roundingMode) {
        return BigDecimal.valueOf(value)
                .setScale(scale, roundingMode)
                .floatValue();
    }

    private static double roundDouble(double value, int scale, RoundingMode roundingMode) {
        return BigDecimal.valueOf(value)
                .setScale(scale, roundingMode)
                .doubleValue();
    }
}